package com.tensquare.notice.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.tensquare.entity.PageResult;
import com.tensquare.entity.Result;
import com.tensquare.notice.client.ArticleClient;
import com.tensquare.notice.client.UserClient;
import com.tensquare.notice.dao.NoticeDao;
import com.tensquare.notice.dao.NoticeFreshDao;
import com.tensquare.notice.pojo.Notice;
import com.tensquare.notice.pojo.NoticeFresh;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.IdWorker;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class NoticeService {

    @Autowired
    private NoticeDao noticeDao;

    @Autowired
    private NoticeFreshDao noticeFreshDao;

    @Autowired
    private UserClient userClient;

    @Autowired
    private ArticleClient articleClient;

    @Autowired
    private IdWorker idWorker;

    /**
     * 添加
     * @param notice
     */
    @Transactional
    public void add(Notice notice) {
        // 设置id
        notice.setId(idWorker.nextId() + "");
        // 默认值设置
        notice.setCreatetime(new Date());
        // "0" 这个直接写一个常量，硬编码：称为魔鬼字符串/数字
        // 一定要加上注释。if("1".equals(type)){ .... }
        //               if(对象.equals(常量) => if(常量.equals(对象))
        // nullpointexception: null.方法()  对象.方法()
        // notice = xxxService.get();   notice有可能为空，notice.getId()=>空指针
        notice.setState("0");
        noticeDao.insert(notice);


        /*
        此处的功能由RabbitMQ替换了，不再需要
        Eric at 2020-02-22

        // 添加新通知数据
        NoticeFresh noticeFresh = new NoticeFresh();
        noticeFresh.setNoticeId(notice.getId());
        // 接收通知的用户id
        noticeFresh.setUserId(notice.getReceiverId());
        noticeFreshDao.insert(noticeFresh);*/

    }

    /**
     * 通过id查询
     * @param noticeId
     * @return
     */
    public Notice findById(String noticeId) {
        Notice notice = noticeDao.selectById(noticeId);
        // 调用用户微服查询操作者的名称，设置到notice对象中
        if(null != notice) {
            setOperatorName(notice);
            // 如果是文章类型，则要调用文章微服查询文章的标题，设置到notice对象
            if ("article".equals(notice.getTargetType())) {
                setArticleTitle(notice);
            }
        }
        return notice;
    }

    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    public PageResult<Notice> findPage(int page, int size) {
        // 分页对象
        Page<Notice> noticePage = new Page<Notice>(page,size);
        // 查询结果集
        List<Notice> notices = noticeDao.selectPage(noticePage, null);
        // 设置操作者名称与文章标题
        if(null != notices){
            for (Notice notice : notices) {
                setOperatorName(notice); //缓存 Map<String,Name> id
                setArticleTitle(notice); // Map<String,title> id
            }
        }
        // 返回分页结果对象
        return new PageResult<Notice>(noticePage.getTotal(), notices);
    }

    /**
     * 修改通知
     * @param notice
     */
    public void update(Notice notice) {
        // 待通知表不需要操作，因为通知的主键不动
        noticeDao.updateById(notice);
    }

    /**
     * 删除
     * @param noticeId
     */
    @Transactional
    public void deleteById(String noticeId) {
        // 删除待通知表数据
        // 通过通知id删除
        EntityWrapper<NoticeFresh> noticeFreshWrapper = new EntityWrapper<NoticeFresh>();
        noticeFreshWrapper.eq("noticeId", noticeId);
        noticeFreshDao.delete(noticeFreshWrapper);
        // 删除通知数据
        noticeDao.deleteById(noticeId);
    }

    /**
     * 根据用户id查询该用户的待推送消息（新消息）
     * @param userId
     * @param page
     * @param size
     * @return
     */
    public PageResult<NoticeFresh> freshPage(String userId, int page, int size) {
        // 构建查询条件
        EntityWrapper<NoticeFresh> where = new EntityWrapper<NoticeFresh>();
        where.eq("userId", userId);
        // 构建分页对象
        Page<NoticeFresh> noticeFreshPage = new Page<NoticeFresh>(page,size);
        // 返回分页结果
        List<NoticeFresh> list = noticeFreshDao.selectPage(noticeFreshPage, where);
        return new PageResult<NoticeFresh>(noticeFreshPage.getTotal(), list);
    }

    /**
     * 调用用户微服查询操作者名称并设置到通知对象中
     * @param notice
     */
    private void setOperatorName(Notice notice){
        //获取操作者id
        String userId = notice.getOperatorId();
        Result result = userClient.selectById(userId);
        if(result.isFlag()){
            // 调用成功, data类型为(微服间调用使用的是restFul风格，
            // 微服间传输的数据使用的是json,data的类型为Map)
            Map<String, Object> data = (Map<String, Object>)result.getData();
            if(null != data) {
                String nickname = (String) data.get("nickname");
                notice.setOperatorName(nickname);
            }
        }
    }

    /**
     * 调用文章微服查询文章标题并设置到通知对象中
     * @param notice
     */
    private void setArticleTitle(Notice notice){
        Result result = articleClient.findById(notice.getTargetId());
        if(result.isFlag()){
            // 有结果
            Map<String, Object> resultData = (Map<String, Object>) result.getData();
            if(null != resultData) {
                notice.setTargetName(((String) resultData.get("title")));
                //String title = (String) resultData.get("title");// 如果map返回空值，这里不会抛指针
                //String title1 = resultData.get("title").toString();//如果map返回空值，这里会抛指针
            }
        }
    }

}
